import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { Store } from '@ngxs/store';
import { Severity, Vulnerability } from 'app/model/application.model';
import { ApplicationsState, ApplicationStateModel } from 'app/store/applications.state';
import { WorkflowState, WorkflowStateModel } from 'app/store/workflow.state';

@Component({
    selector: 'app-vulnerabilities',
    templateUrl: './vulnerabilities.html',
    styleUrls: ['./vulnerabilities.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class VulnerabilitiesComponent {

    @Input() edit = false;

    orderedVulnerabilities: Vulnerability[];
    summary = {
        total: 0,
        defcon: 0,
        deltaDefcon: 0,
        critical: 0,
        deltaCritical: 0,
        high: 0,
        deltaHigh: 0,
        medium: 0,
        deltaMedium: 0,
        low: 0,
        deltaLow: 0,
        negligible: 0,
        deltaNegligible: 0,
        unknown: 0,
        deltaUnknown: 0,
    };
    filter = '';

    constructor(private _store: Store) {
        let nr = (<WorkflowStateModel>this._store.selectSnapshot(WorkflowState)).workflowNodeRun;
        if (nr) {
            this.initVulnerabilities(nr.vulnerabilities_report.report.vulnerabilities);
            if (nr.vulnerabilities_report.report.previous_run_summary) {
                this.calculateDelta(nr.vulnerabilities_report.report.previous_run_summary);
            } else if (nr.vulnerabilities_report.report.default_branch_summary) {
                this.calculateDelta(nr.vulnerabilities_report.report.default_branch_summary);
            }
            this.edit = false;
        } else {
            let app = (<ApplicationStateModel>this._store.selectSnapshot(ApplicationsState)).application;
            this.initVulnerabilities(app.vulnerabilities);
        }

    }

    updateFilter(v: Vulnerability): void {
        this.filter = v.component + ' ' + v.version;
    }

    calculateDelta(m: { [key: string]: number}): void {
        Object.keys(m).forEach( k => {
           switch (k) {
               case Severity.DEFCON1:
                   this.summary.deltaDefcon = this.summary.defcon - m[k];
                   break;
               case Severity.CRITICAL:
                   this.summary.deltaCritical = this.summary.critical - m[k];
                   break;
               case Severity.HIGH:
                   this.summary.deltaHigh = this.summary.high - m[k];
                   break;
               case Severity.MEDIUM:
                   this.summary.deltaMedium = this.summary.medium - m[k];
                   break;
               case Severity.LOW:
                   this.summary.deltaLow = this.summary.low - m[k];
                   break;
               case Severity.NEGLIGIBLE:
                   this.summary.deltaNegligible = this.summary.negligible - m[k];
                   break;
               case Severity.UNKNOWN:
                   this.summary.deltaUnknown = this.summary.unknown - m[k];
                   break;
           }
        });
    }

    initVulnerabilities(data: Array<Vulnerability>): void {
        if (data) {
            let defcon1 = new Array<Vulnerability>();
            let critical = new Array<Vulnerability>();
            let high = new Array<Vulnerability>();
            let medium = new Array<Vulnerability>();
            let low = new Array<Vulnerability>();
            let negligible = new Array<Vulnerability>();
            let unknown = new Array<Vulnerability>();
            data.forEach(v => {
                switch (v.severity) {
                    case Severity.DEFCON1:
                        defcon1.push(v);
                        break;
                    case Severity.CRITICAL:
                        critical.push(v);
                        break;
                    case Severity.HIGH:
                        high.push(v);
                        break;
                    case Severity.MEDIUM:
                        medium.push(v);
                        break;
                    case Severity.LOW:
                        low.push(v);
                        break;
                    case Severity.NEGLIGIBLE:
                        negligible.push(v);
                        break;
                    case Severity.UNKNOWN:
                        unknown.push(v);
                        break;
                }
            });
            this.summary.defcon = defcon1.length;
            this.summary.critical = critical.length;
            this.summary.high = high.length;
            this.summary.medium = medium.length;
            this.summary.low = low.length;
            this.summary.negligible = negligible.length;
            this.summary.unknown = unknown.length;
            this.summary.total = this.summary.critical + this.summary.defcon + this.summary.high + this.summary.medium
                + this.summary.low + this.summary.negligible + this.summary.unknown;

            this.orderedVulnerabilities = new Array<Vulnerability>();
            this.orderedVulnerabilities.push(...defcon1.concat(critical, high, medium, low, negligible, unknown));
        }
    }
}
